/*
 * PhysicSpaceBridge.h
 *
 *  Created on: Sep 28, 2009
 *      Author: Falken
 */

#ifndef PHYSICSSPACEBRIDGE_H_
#define PHYSICSSPACEBRIDGE_H_

#include <jni.h>
#include <map.h>
#include "btBulletDynamicsCommon.h"

struct ltint
{
  bool operator()(const int s1, const int s2) const
  {
    return s1 < s2;
  }
};

class PhysicsSpaceBridge {
private:
	btDynamicsWorld* dynWorld;
	jobject javaPhysicsSpace;

	jclass physicsSpaceClass;
	jmethodID method_physicsSpace_applyPhysicsMovement;

	jclass rigidBodyClass;
	jmethodID method_rigidBody_constructor;
	jmethodID method_rigidBody_getNativeBulletHandle;
	jmethodID method_rigidBody_getShapes;

	jclass geometryClass;
	jmethodID method_geometry_getLocalTranslation;
	jmethodID method_geometry_getLocalRotation;
	jmethodID method_geometry_getLocalScale;
	jmethodID method_geometry_getShape;

	jclass meshClass;
	jmethodID method_mesh_getVerticesArray;
	jmethodID method_mesh_getTrianglesArray;

	jclass jointClass;
	jmethodID method_joint_getNativeBulletHandle;

	jclass IAE;

	map<jlong,jobject> javaRigidBodies;
	map<jlong,btRigidBody*> bulletRigidBodies;
	map<jlong,jobject> javaJoints;
	map<jlong,btTypedConstraint*> bulletConstraints;
	map<jlong,int> jointTypes;

	long rigidBodyIndex;
	long constraintIndex;

	btScalar stepSize;

	bool initJavaMethodHandles(JNIEnv*);
public:

	PhysicsSpaceBridge(JNIEnv*,jobject);
	jlong buildRigidBody(JNIEnv*,jobject javaRB, btVector3 pos, btQuaternion rot, btVector3 scale, btTransform com, btVector3 linVel, btVector3 angVel, float mass);
	jlong buildJoint(JNIEnv*,jobject javaJoint, int jointType, btTransform refA, btTransform refB, jlong rbAHandle, jlong rbBHandle, jboolean collideWithSelf);
	float getPosition(jlong jointHandle, int axisIndex);
	float getVelocity(jlong jointHandle, int axisIndex);
	void setRigidBodyInfo(jlong rbHandle, float tx, float ty, float tz, float rx, float ry, float rz, float rw, float lvx, float lvy, float lvz, float avx, float avy, float avz);
	void applyForces(jlong rbHandle, float fx, float fy, float fz, float px, float py, float pz, float tx, float ty, float tz);
	void updateJointAxis(jlong jointHandle, int axisIndex, float availableAccel, float desiredVel, float posMin, float posMax);
	void step(JNIEnv*,float timestep);
	void setWorldTransform(JNIEnv*,jobjectArray,jdoubleArray,jdoubleArray,jdoubleArray,jdoubleArray,jdoubleArray,jdoubleArray,jdoubleArray);
	virtual ~PhysicsSpaceBridge();
};

#endif /* PHYSICSSPACEBRIDGE_H_ */
